package edu.uab.enronemail.request;

import java.io.BufferedReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import edu.uab.enronemail.helper.StringUtility;

public class EmailDocument {

	public static String FROM_FIELD = "From";
	public static String TO_FIELD = "To";
	public static String CC_FIELD = "Cc";
	public static String BCC_FIELD = "Bcc";
	public static String BODY = "body";
	public static String SUBJECT_FIELD = "Subject";
	public static String DATE_FIELD = "Date";
	public static String DELIMITTER = ",";
	public static String[] CHARACTERS = {
			"\\.",
			"\n",
			"\\*",
			"<",
			">",
			"#",
			"$",
			"[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*(\\.[A-Za-z]{2,})$"
	// Email Address Regular expression
	};

	public static Set<String> stopWords;

	public static void configureStopWords(BufferedReader fileReader) {
		if (stopWords == null)
			stopWords = new HashSet<String>();
		else
			return;

		String line = null;
		try {
			while ((line = fileReader.readLine()) != null) {
				stopWords.add(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public String findValueForField(String field) {
		if (FROM_FIELD.equals(field))
			return getFrom();
		else if (TO_FIELD.equals(field))
			return StringUtility.joinStringsByDelimitter(getTo(), DELIMITTER);
		else if (CC_FIELD.equals(field))
			return StringUtility.joinStringsByDelimitter(getCc(), DELIMITTER);
		else if (BCC_FIELD.equals(field))
			return StringUtility.joinStringsByDelimitter(getBcc(), DELIMITTER);
		else if (SUBJECT_FIELD.equals(field))
			return getSubject();
		else if (BODY.equals(field))
			return getEmailBody();
		else
			return otherParts.get(field);
	}

	public void addParts(String field, String value) {
		if (FROM_FIELD.equals(field))
			setFrom(value);
		else if (TO_FIELD.equals(field))
			setTo(Arrays.asList(value.split(DELIMITTER)));
		else if (CC_FIELD.equals(field))
			setCc(Arrays.asList(value.split(DELIMITTER)));
		else if (BCC_FIELD.equals(field))
			setBcc(Arrays.asList(value.split(DELIMITTER)));
		else if (SUBJECT_FIELD.equals(field))
			setSubject(value);
		else
			addOtherParts(field, value);
	}

	public void setEmailBodyTokens(String body) {
		System.out.println("Before splitting :: " + body);
		body = body.substring(body.lastIndexOf("Subject:")
				+ "Subject:".length());

		for (String character : CHARACTERS)
			body = body.replaceAll(character, "");

		System.out.println("Body to split :: " + body);
		emailBodyTokens = new HashSet<String>();
		String[] bodyTokens = body.split(" ");
		for (String bodyToken : bodyTokens) {
			if (!stopWords.contains(bodyToken.toLowerCase()))
				emailBodyTokens.add(bodyToken);
		}
	}

	private void addOtherParts(String field, String value) {
		if (otherParts == null)
			otherParts = new HashMap<String, String>();

		if (findValueForField(field) != null) {

		} else
			otherParts.put(field, value);
	}

	public String toString() {
		String str = getFrom() + "\n";
		str += getSubject() + "\n";
		str += getEmailBody().substring(0, 20) + ".......\n";
		return str;
	}

	public String getFrom() {
		return from;
	}

	private void setFrom(String from) {
		this.from = from;
	}

	public List<String> getTo() {
		return to;
	}

	private void setTo(List<String> to) {
		this.to = to;
	}

	public List<String> getCc() {
		return cc;
	}

	private void setCc(List<String> cc) {
		this.cc = cc;
	}

	public List<String> getBcc() {
		return bcc;
	}

	private void setBcc(List<String> bcc) {
		this.bcc = bcc;
	}

	public String getEmailBody() {
		return emailBody;
	}

	public void setEmailBody(String emailBody) {
		this.emailBody = emailBody;
	}

	public String getSubject() {
		return subject;
	}

	private void setSubject(String subject) {
		this.subject = subject;
	}

	public Set<String> getEmailBodyTokens() {
		return emailBodyTokens;
	}

	private String from;
	private List<String> to;
	private List<String> cc;
	private List<String> bcc;
	private String emailBody;
	private String subject;
	private Set<String> emailBodyTokens;
	private Map<String, String> otherParts = null;

}
